package com.tjf.record.xunfei;

import android.util.Log;

import com.tjf.record.MySocketCallBack;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class WebSocketMager {
    private static String BASE_URL = "wss://rtasr.xfyun.cn/v1/ws";

    private static String ORIGIN = "https://rtasr.xfyun.cn/v1/ws";

    final SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss.SSS");

    MyWebSocketClient client;

    private MySocketCallBack myCallBack;

    private static int code = 1;

    public void initWebSocket(String appId, String appServer, MySocketCallBack myCallBack) {
        initWebSocket(appId, appServer, null, myCallBack);
    }

    public void initWebSocket(String appId, String appServer, String lang, MySocketCallBack myCallBack) {
        initWebSocket(appId, appServer, lang, null, myCallBack);
    }

    /**
     * 初始化websocket
     */
    public void initWebSocket(String appId, String appServer, String lang, String targetLang, MySocketCallBack myCallBack) {
        this.myCallBack = myCallBack;
        URI url = null;
        try {
            if (lang != null && targetLang != null) {
                url = new URI(BASE_URL + getHandShakeParams(appId, appServer)
                        + "&lang=" + lang + "&transType=normal&transStrategy=2&targetLang=" + targetLang);
            } else if (lang != null) {
                url = new URI(BASE_URL + getHandShakeParams(appId, appServer)
                        + "&lang=" + lang + "&transType=normal&transStrategy=2");
            } else {
                url = new URI(BASE_URL + getHandShakeParams(appId, appServer));
            }
            DraftWithOrigin draft = new DraftWithOrigin(ORIGIN);
            CountDownLatch handshakeSuccess = new CountDownLatch(1);
            CountDownLatch connectClose = new CountDownLatch(1);
            client = new MyWebSocketClient(url, draft, handshakeSuccess, connectClose);
            System.out.println("测试" + url);
            client.connect();
            // 等待握手成功
            handshakeSuccess.await();

        } catch (URISyntaxException e) {
            Log.d("WebSocketMager", "Connection error: ", e);
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }


    }


    // 生成握手参数
    public String getHandShakeParams(String appId, String secretKey) {
        String ts = System.currentTimeMillis() / 1000 + "";
        String signa = "";
        try {
            signa = XfEncryptUtil.HmacSHA1Encrypt(XfEncryptUtil.MD5(appId + ts), secretKey);
            return "?appid=" + appId + "&ts=" + ts + "&signa=" + URLEncoder.encode(signa, "UTF-8");
        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }
        return "";
    }


    public void sendBuff(byte[] bytes) {
        if (client != null) {
            Log.d("WebSocketMager", "=发送数据=");
            client.send(bytes);
        }
    }


    public void close() {
        // 关闭 WebSocket 连接
        if (client != null) {
            client.close();
            client = null;
        }
    }

    public String getCurrentTimeStr() {
        return sdf.format(new Date());
    }

    public class MyWebSocketClient extends WebSocketClient {

        private CountDownLatch handshakeSuccess;
        private CountDownLatch connectClose;

        public MyWebSocketClient(URI serverUri, Draft protocolDraft, CountDownLatch handshakeSuccess, CountDownLatch connectClose) {
            super(serverUri, protocolDraft);
            this.handshakeSuccess = handshakeSuccess;
            this.connectClose = connectClose;
            if (serverUri.toString().contains("wss")) {
                trustAllHosts(this);
            }
        }

        @Override
        public void onOpen(ServerHandshake handshake) {
            System.out.println(getCurrentTimeStr() + "\t连接建立成功！");
            handshakeSuccess.countDown();
        }

        public String getContent(String message) {
            StringBuilder resultBuilder = new StringBuilder();
            try {
                JSONObject messageObj = new JSONObject(message);
                JSONObject cn = messageObj.getJSONObject("cn");
                if (cn != null) {
                    JSONObject st = cn.getJSONObject("st");
                    if (st != null) {
                        JSONArray rtArr = st.getJSONArray("rt");
                        for (int i = 0; i < rtArr.length(); i++) {
                            JSONObject rtArrObj = rtArr.getJSONObject(i);
                            JSONArray wsArr = rtArrObj.getJSONArray("ws");
                            for (int j = 0; j < wsArr.length(); j++) {
                                JSONObject wsArrObj = wsArr.getJSONObject(j);
                                JSONArray cwArr = wsArrObj.getJSONArray("cw");
                                for (int k = 0; k < cwArr.length(); k++) {
                                    JSONObject cwArrObj = cwArr.getJSONObject(k);
                                    String wStr = cwArrObj.getString("w");
                                    if (wStr != null) {
                                        resultBuilder.append(wStr);
                                    }
                                }
                            }
                        }
                        //【最终】识别结果：
                        String type = st.getString("type");
                        code = 1;
                        if (type.equals("0")) {
                            Log.d("WebSocketMager", "最终识别结果  ==：" + resultBuilder.toString());
                            code = 0;
                        }
                    }
                }
            } catch (Exception e) {
                return message; // 返回原始消息
            }
            return resultBuilder.toString();
        }


        @Override
        public void onMessage(String msg) {
            JSONObject msgObj = null;
            try {
                msgObj = new JSONObject(msg);
                String action = msgObj.getString("action");
                Log.d("WebSocketMager", "action: " + action);
                if (Objects.equals("started", action)) {
                    myCallBack.onStart();
                    // 握手成功
                    Log.d("WebSocketMager", getCurrentTimeStr() + "\t握手成功！sid: " +
                            msgObj.getString("sid"));
                    handshakeSuccess.countDown();
                } else if (Objects.equals("result", action)) {
                    String data = msgObj.getString("data");
                    if (data != null) {
                        Log.d("WebSocketMager", "111111");
                        JSONObject object = new JSONObject();
                        try {
                            object.put("data", getContent(data)); /// getContent(data)
                            object.put("code", code);
                        } catch (JSONException e) {
                            throw new RuntimeException(e);
                        }
                        myCallBack.onSuccess(object);
                        // 转写结果
//                    System.out.println(getCurrentTimeStr() + "\tresult: " + getContent(data));
                    } else {
                        // 处理 data 为 null 的情况
                        Log.d("WebSocketMager", getCurrentTimeStr() + "\tdata 为 null，无法处理结果");
                    }
                } else if (Objects.equals("error", action)) {
                    // 连接发生错误
                    JSONObject object = new JSONObject();

                    object.put("code", msgObj.getString("code"));
                    object.put("desc", msgObj.getString("desc"));
                    object.put("action", action);

                    myCallBack.onFail(object);
                }
            } catch (JSONException e) {
                throw new RuntimeException(e);
            }
        }


        @Override
        public void onError(Exception e) {
            Log.d("WebSocketMager", getCurrentTimeStr() + "\t连接发生错误：" + e.getMessage() + ", " + new Date());
            e.printStackTrace();
            JSONObject object = new JSONObject();
            try {
                object.put("wesocketError", "连接发生错误");
            } catch (JSONException ex) {
                throw new RuntimeException(ex);
            }
            myCallBack.onFail(object);
        }

        @Override
        public void onClose(int arg0, String arg1, boolean arg2) {
            Log.d("WebSocketMager", getCurrentTimeStr() + "\t链接关闭");
            connectClose.countDown();
            JSONObject object = new JSONObject();
            try {
                object.put("wesocketError", "链接关闭");
            } catch (JSONException e) {
                throw new RuntimeException(e);
            }
            myCallBack.onComplete();

        }

        @Override
        public void onMessage(ByteBuffer bytes) {
            try {
                Log.d("WebSocketMager", getCurrentTimeStr() + "\t服务端返回：" + new String(bytes.array(), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }

        public void trustAllHosts(MyWebSocketClient appClient) {
            Log.d("WebSocketMager", "wss");
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                @Override
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new java.security.cert.X509Certificate[]{};
                }

                @Override
                public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                    // TODO Auto-generated method stub

                }

                @Override
                public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                    // TODO Auto-generated method stub

                }
            }};

            try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                appClient.setSocket(sc.getSocketFactory().createSocket());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
